package data

import (
	"context"
	"gitee.com/jacktuotuo/coolcar/app/user/internal/biz"
	mgo "gitee.com/jacktuotuo/coolcar/pkg/mongo"
	"github.com/go-kratos/kratos/v2/log"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/bson/primitive"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
)

type OpenIdResolver interface {
	Resolve(code string) (string, error)
}

type TokenGenerator interface {
	GenerateToken(accountId string) (token string, expiresTime int32, err error)
}

type userRepo struct {
	data      *Data
	log       *log.Helper
	resolver  OpenIdResolver
	generator TokenGenerator
	userColl  *mongo.Collection
	newObjID  func() primitive.ObjectID
}

func (r *userRepo) GenerateToken(accountId string) (string, int32, error) {
	return r.generator.GenerateToken(accountId)
}

const OpenIDField = "open_id"

func (r *userRepo) QueryAccountId(ctx context.Context, openId string) (string, error) {

	insertID := r.newObjID()

	one := r.userColl.FindOneAndUpdate(
		ctx,
		bson.M{OpenIDField: openId},
		mgo.SetOnInsert(bson.M{mgo.IDFieldName: insertID, OpenIDField: openId}),
		options.FindOneAndUpdate().SetUpsert(true).SetReturnDocument(options.After),
	)

	var row mgo.IDField

	err := one.Decode(&row)
	if err != nil {
		return "", err
	}
	return row.ID.Hex(), nil
}

func (r *userRepo) CreateUser(ctx context.Context, u *biz.User) error {
	return nil
}

func (r *userRepo) ResolveOpenId(code string) (string, error) {
	return r.resolver.Resolve(code)
}
